package com.nasa.sentinel.nacos;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.nacos.api.PropertyKeyConst;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Properties;

/**
 * <p>sentinel nacos data source configuration</p >
 *
 * @author youyoukele
 * @version 1.0
 * @date 2021/10/12
 */
@Slf4j
@EnableConfigurationProperties(SentinelNacosConfigProperties.class)
public class SentinelNacosDataSourceConfiguration {

    @Value("${spring.application.name}")
    private String applicationName;

    @Autowired
    private SentinelNacosConfigProperties properties;

    @PostConstruct
    public void init() {
        log.info("start init flow rule. properties:{}", properties);
        String serverAddr = ObjectUtil.defaultIfNull(properties.getServerAddr(), SpringUtil.getProperty("spring.cloud.nacos.config.server-addr"));
        String namespace = ObjectUtil.defaultIfNull(properties.getNamespace(),SpringUtil.getProperty("spring.cloud.nacos.config.namespace"));
        String group = ObjectUtil.defaultIfNull(properties.getGroup(),SpringUtil.getProperty("spring.cloud.nacos.config.group"));
        String dataId = ObjectUtil.defaultIfBlank(properties.getDataId(), "sentinel.flow.rule." + applicationName + ".json");

        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
        properties.put(PropertyKeyConst.NAMESPACE, namespace);

        try {
            Converter<String, List<FlowRule>> converter = source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
            });
            ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(properties, group, dataId, converter);
            FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
            log.info("flow rule source:{}", flowRuleDataSource.readSource());
        } catch (Exception ignore) {
            log.warn("Sentinel Nacos DataSource Configuration", ignore);
        }
    }

}
